/**
 * 使用形状上下文距离提取器
 */
#include <opencv2/opencv.hpp>
#include <algorithm>
#include <string>
#include <iostream>

using namespace std;

static vector<cv::Point> sampleContour(const cv::Mat& image, int n = 300){
    vector<vector<cv::Point>> _countours;
    vector<cv::Point> all_points;
    cv::findContours(image, _countours, cv::RETR_LIST, cv::CHAIN_APPROX_NONE);

    for (size_t i = 0; i < _countours.size(); i++) {
        for (size_t j = 0; j < _countours[i].size(); j++) {
            all_points.push_back(_countours[i][j]);
        }
    }

    // if too little points, replicate them
    int dummy = 0;
    for (int add = (int)all_points.size(); add < n; add++)
        all_points.push_back(all_points[dummy++]);

    // sample uniformly
    random_shuffle(all_points.begin(), all_points.end());
    vector<cv::Point> sampled;
    for (int i = 0; i < n; i++)
        sampled.push_back(all_points[i]);
    
    return sampled;
}

int main(int argc, char** argv) {
    string path = "";
    int indexQuery = 1;
    
    cv::Ptr<cv::ShapeContextDistanceExtractor> mysc = cv::createShapeContextDistanceExtractor();
    
    cv::Size sz2Sh(300, 300);
    cv::Mat image1 = cv::imread(argv[1], cv::IMREAD_GRAYSCALE);
    cv::Mat image2 = cv::imread(argv[2], cv::IMREAD_GRAYSCALE);

    vector<cv::Point> c1 = sampleContour(image1);
    vector<cv::Point> c2 = sampleContour(image2);
    float dis = mysc->computeDistance(c1, c2);

    cout << "shape context distance between " << argv[1] << " and " << argv[2] << " is: " << dis << endl;

    return 0;
}